home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / posix / __sigvec.c < prev    next >
C/C++ Source or Header  |  1994-05-16  |  4KB  |  161 lines

  1. /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <signal.h>
  21. #include <errno.h>
  22. #include <stddef.h>
  23.  
  24.  
  25. /* We use a wrapper handler to support SV_RESETHAND.  */
  26.  
  27. static __sighandler_t wrapped_handlers[NSIG];
  28. static sigset_t wrapped_masks[NSIG];
  29.  
  30. static void
  31. DEFUN(wrapper_handler, (sig), int sig)
  32. {
  33.   int save;
  34.   struct sigaction act;
  35.  
  36.   act.sa_handler = SIG_DFL;
  37.   act.sa_mask = wrapped_masks[sig];
  38.   act.sa_flags = 0;
  39.   save = errno;
  40.   (void) __sigaction(sig, &act, (struct sigaction *) NULL);
  41.   errno = save;
  42.  
  43.   (*wrapped_handlers[sig])(sig);
  44. }
  45.  
  46. static
  47. #ifdef    __GNUC__
  48. inline
  49. #endif
  50. int
  51. DEFUN(convert_mask, (set, mask), sigset_t *set AND CONST int mask)
  52. {
  53.   register int sig;
  54.  
  55.   if (sizeof(*set) == sizeof(mask))
  56.     {
  57.       *(int *) set = mask;
  58.       return 0;
  59.     }
  60.  
  61.   if (__sigemptyset(set) < 0)
  62.     return -1;
  63.  
  64.   for (sig = 1; sig < NSIG; ++sig)
  65.     if (mask & sigmask(sig))
  66.       if (__sigaddset(set, sig) < 0)
  67.     return -1;
  68.  
  69.   return 0;
  70. }
  71.  
  72. /* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
  73.    of VEC.  The signals in `sv_mask' will be blocked while the handler runs.
  74.    If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be
  75.    reset to SIG_DFL before `sv_handler' is entered.  If OVEC is non-NULL,
  76.    it is filled in with the old information for SIG.  */
  77. int
  78. DEFUN(__sigvec, (sig, vec, ovec),
  79.       int sig AND CONST struct sigvec *vec AND struct sigvec *ovec)
  80. {
  81.   struct sigaction old;
  82.  
  83.   if (vec == NULL || !(vec->sv_flags & SV_RESETHAND))
  84.     {
  85.       struct sigaction new, *n;
  86.  
  87.       if (vec == NULL)
  88.     n = NULL;
  89.       else
  90.     {
  91.       n = &new;
  92.       n->sa_handler = vec->sv_handler;
  93.       if (convert_mask (&n->sa_mask, vec->sv_mask) < 0)
  94.         return -1;
  95.       n->sa_flags = 0;
  96.       
  97.       if (vec->sv_flags & SV_ONSTACK)
  98.         {
  99. #ifdef SA_ONSTACK
  100.           n->sa_flags |= SA_ONSTACK;
  101. #else
  102.           errno = ENOSYS;
  103.           return -1;
  104. #endif
  105.         }
  106. #ifdef SA_RESTART
  107.       if (!(vec->sv_flags & SV_INTERRUPT))
  108.         n->sa_flags |= SA_RESTART;
  109. #endif
  110.     }
  111.  
  112.       if (__sigaction (sig, n, &old) < 0)
  113.     return -1;
  114.     }
  115.   else
  116.     {
  117.       struct sigaction wrapper;
  118.  
  119.       wrapper.sa_handler = wrapper_handler;
  120.       wrapped_handlers[sig] = vec->sv_handler;
  121.       if (convert_mask (&wrapped_masks[sig], vec->sv_mask) < 0)
  122.     return -1;
  123.  
  124.       if (__sigaction (sig, &wrapper, &old) < 0)
  125.     return -1;
  126.     }
  127.  
  128.   if (ovec != NULL)
  129.     {
  130.       register int i;
  131.       int mask = 0;
  132.  
  133.       if (sizeof (int) == sizeof (sigset_t))
  134.     mask = *(int *) &old.sa_mask;
  135.       else
  136.     for (i = 1; i < NSIG; ++i)
  137.       if (__sigismember(&old.sa_mask, i))
  138.         mask |= sigmask(i);
  139.  
  140.       ovec->sv_mask = mask;
  141.       ovec->sv_flags = 0;
  142. #ifdef SA_ONSTACK
  143.       if (old.sa_flags & SA_ONSTACK)
  144.     ovec->sv_flags |= SV_ONSTACK;
  145. #endif
  146. #ifdef SA_RESTART
  147.       if (!(old.sa_flags & SA_RESTART))
  148. #endif
  149.     ovec->sv_flags |= SV_INTERRUPT;
  150.       if (old.sa_handler == wrapper_handler)
  151.     {
  152.       ovec->sv_flags |= SV_RESETHAND;
  153.       ovec->sv_handler = wrapped_handlers[sig];
  154.     }
  155.       else
  156.     ovec->sv_handler = old.sa_handler;
  157.     }
  158.  
  159.   return 0;
  160. }
  161.